/*
 * MIT License
 *
 * Copyright (c) 2020 wen.gu <454727014@qq.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/***************************************************************************
 * Name: xutils.cpp
 *
 * Purpose: Helper API define and implementation
 *
 * Developer:
 *   wen.gu , 2023-10-26
 *
 * TODO:
 *
 ***************************************************************************/

#include "xbus/com/xutils.h"

#include <map>

#define PROT_PREFIX_UDS "uds://"
#define PROT_PREFIX_TCP "tcp://"
#define PROT_PREFIX_UDP "udp://"
#define PROT_PREFIX_SHM "shm://"

#define COM_TYPE_MAP(type, prefix) case type: return prefix; break

namespace xbus::com {



class XComTypeMapper {
public:
    using TypeMap = std::map<std::string, XComType>;
protected:
    XComTypeMapper() {
        type_map_[PROT_PREFIX_UDS] = XComType::UDS;
        type_map_[PROT_PREFIX_TCP] = XComType::TCP;
        type_map_[PROT_PREFIX_UDP] = XComType::UDP;
        type_map_[PROT_PREFIX_SHM] = XComType::SHM;
    }
public:
    static XComTypeMapper& getInstance() {
        static XComTypeMapper ctm;
        return ctm;
    }
public:
    TypeMap type_map_;
};



XComType ParseComType(const std::string& url) {
    size_t pos = url.find_first_of("://");

    if (pos == std::string::npos) {
        return XComType::None;
    }

    std::string prot_prefix = url.substr(0, pos + 3); /** +3 is to include "://" */

    auto& type_map = XComTypeMapper::getInstance().type_map_;

    auto it = type_map.find(prot_prefix);

    if (it != type_map.end()) {
        return it->second;
    }

    return XComType::None;
}

const char* ComTypePrefix(XComType type) {
    switch (type) {
    COM_TYPE_MAP(XComType::UDS, PROT_PREFIX_UDS);
    COM_TYPE_MAP(XComType::TCP, PROT_PREFIX_TCP);
    COM_TYPE_MAP(XComType::UDP, PROT_PREFIX_UDP);
    COM_TYPE_MAP(XComType::SHM, PROT_PREFIX_SHM);
    default: break;
    }

    return "unkown";
}

core::XSocketType ComType2SockType(XComType type) {
    switch (type) {
    case XComType::UDS: return core::XSocketType::UDS; break;
    case XComType::TCP: return core::XSocketType::TCP; break;
    case XComType::UDP: return core::XSocketType::UDP; break;
    default:  break;
    }

    return core::XSocketType::None;
}

XComType SockType2ComType(core::XSocketType type) {
    switch (type) {
    case core::XSocketType::UDS: return XComType::UDS; break;
    case core::XSocketType::TCP: return XComType::TCP; break;
    case core::XSocketType::UDP: return XComType::UDP; break;
    default:  break;
    }

    return XComType::None;
}

} //namespace xbus::com